﻿/*********************************************************************************
 *Author:         OnClick
 *Version:        1.0
 *UnityVersion:   2018.3.1f1
 *Date:           2019-03-31
 *Description:    IFramework
 *History:        2018.11--
*********************************************************************************/
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using System.Text.RegularExpressions;

namespace IFramework
{
    public class DefaultCsv
	{
        public void Read<T>(string text) where T : IDataModel, new()
        {
            PropertyInfo[] infos = typeof(T).GetProperties();
            string[] Lines = text.Replace("\r\n", "\n").Split('\n');
            for (int i = 1; i < Lines.Length - 1; i++)
            {
                T t = new T();
                SortedList<int, string> sortedList = GetLineItems(Lines[i]);
                for (int j = 0; j < infos.Length; j++)
                {
                    infos[j].SetValue(t, sortedList[j].TryParse(infos[j].PropertyType), null);
                }
                t.GetDictionary<T>().Add(t.IineID, t);
            }
        }
        public Dictionary<int ,T> Read1<T>(string text) where T : IDataModel, new()
        {
            Dictionary<int, T> dic = new Dictionary<int, T>();
            PropertyInfo[] infos = typeof(T).GetProperties();
            string[] Lines = text.Replace("\r\n", "\n").Split('\n');
            for (int i = 1; i < Lines.Length - 1; i++)
            {
                T t = new T();
                SortedList<int, string> sortedList = GetLineItems(Lines[i]);
                for (int j = 0; j < infos.Length; j++)
                {
                    infos[j].SetValue(t, sortedList[j].TryParse(infos[j].PropertyType), null);
                }
                dic.Add(t.IineID, t);
            }
            return dic;
        }
        public DataTable Read2<T>(string text) where T : IDataModel, new()
        {
            PropertyInfo[] infos = typeof(T).GetProperties();
            string[] Lines = text.Replace("\r\n", "\n").Split('\n');
            DataTable table = new DataTable(typeof(T).Name,typeof(T).Namespace);
            for (int i = 0; i < infos.Length; i++)
            {
                table.Columns.Add(infos[i].Name, infos[i].PropertyType);
            }
            T t = new T();
            for (int i = 1; i < Lines.Length - 1; i++)
            {
                DataRow row = table.NewRow();
                SortedList<int, string> sortedList = GetLineItems(Lines[i]);
                for (int j = 0; j < infos.Length; j++)
                {
                    row[j] = sortedList[j].TryParse(infos[j].PropertyType);
                }
                table.Rows.Add(row);
            }
            return table;
        }
        private SortedList<int, string> GetLineItems(string src)
        {
            if (string.IsNullOrEmpty(src)) return null;
            SortedList<int, string> sl = new SortedList<int, string>();
            src = src.Replace("\"\"", "'");
            var ie = Regex.Matches(src, "[,]?\"([^\"]+)\",", RegexOptions.ExplicitCapture).GetEnumerator();
            while (ie.MoveNext())
            {
                string patn = ie.Current.ToString();
                int key = src.Substring(0, src.IndexOf(patn)).Split(',').Length;
                if (sl.ContainsKey(key)) continue;
                if (src.IndexOf(patn) == 0 && !patn.StartsWith(","))
                {
                    sl.Add(0, patn.Trim(new char[] { ',', '"' }).Replace("'", "\""));
                    src = src.Replace(patn, ",");
                }
                else
                {
                    sl.Add(key, patn.Trim(new char[] { ',', '"' }).Replace("'", "\""));
                    src = src.Replace(patn, ",,");
                }
            }
            src = src.Replace(" ", "");
            src = src.Replace("'", "\"");
            ie = Regex.Matches(src, "\"[\\w]+\":\"[\\w]+\",", RegexOptions.ExplicitCapture).GetEnumerator();
            while (ie.MoveNext())
            {
                string patn = ie.Current.ToString();
                string temp = src.Substring(0, src.IndexOf(patn) + patn.Length - 1);
                src = src.Replace(temp, temp + "\"");
            }
            src = src.Replace("\",", "#");
            src = src.Replace("\"},{\"", "##");
            string[] arr = src.Split(',');
            for (int i = 0; i < arr.Length; i++)
            {
                if (sl.ContainsKey(i)) continue;
                sl.Add(i, arr[i].Trim(new char[] { ',', '"' }).Replace("#", ",").Replace("##", "\"},{\""));
            }
            return sl;
        }

        public string Write<T>() where T : IDataModel, new()
        {
            PropertyInfo[] infos = typeof(T).GetProperties();
            string csvStr = string.Empty;
            for (int i = 0; i < infos.Length - 1; i++)
            {
                csvStr += infos[i].Name + ",";
            }
            csvStr += infos[infos.Length - 1].Name + "\n";
            foreach (var item in new T().GetDictionary<T>().Values)
            {
                for (int i = 0; i < infos.Length - 1; i++)
                {
                    csvStr += FormatLineItem(infos[i].GetValue(item, null).ToString()) + ",";
                }
                csvStr += FormatLineItem(infos[infos.Length - 1].GetValue(item, null).ToString()) + "\n";
            }
            return csvStr;
        }
        private string FormatLineItem(string src)
        {
            if (src.Contains("\""))
                return "\"" + src.Replace("\"", "\"\"") + "\"";
            if (!src.Contains("\"") && src.Contains(","))
                return "\"" + src + "\"";
            return src;
        }
        public string Write1<T>(Dictionary<int,T> dic) where T : IDataModel, new()
        {
            PropertyInfo[] infos = typeof(T).GetProperties();
            string csvStr = string.Empty;
            for (int i = 0; i < infos.Length - 1; i++)
            {
                csvStr += infos[i].Name + ",";
            }
            csvStr += infos[infos.Length - 1].Name + "\n";
            foreach (var item in dic.Values)
            {
                for (int i = 0; i < infos.Length - 1; i++)
                {
                    csvStr += FormatLineItem(infos[i].GetValue(item, null).ToString()) + ",";
                }
                csvStr += FormatLineItem(infos[infos.Length - 1].GetValue(item, null).ToString()) + "\n";
            }
            return csvStr;
        }
        public string Write2<T>(DataTable table) where T : IDataModel, new()
        {
            PropertyInfo[] infos = typeof(T).GetProperties();
            string csvStr = string.Empty;
            for (int i = 0; i < infos.Length - 1; i++)
            {
                csvStr += infos[i].Name + ",";
            }
            csvStr += infos[infos.Length - 1].Name + "\n";
            for (int i = 0; i < table.Rows.Count; i++)
            {
                for (int j = 0; j < infos.Length-1; j++)
                {
                    csvStr += FormatLineItem(table.Rows[i][j].ToString()) + ",";
                }
                csvStr += FormatLineItem(table.Rows[i][infos.Length-1].ToString()) + "\n";
            }
            return csvStr;
        }

    }
}
